package com.example.entity;

/**
 * 在 Java 中，Cloneable 是一个标记接口（marker interface），它的作用是允许对象进行克隆（复制）。
 * 它没有任何方法，仅作为一种“标志”告诉 Java 虚拟机：这个类允许使用 Object.clone() 方法来克隆其实例对象。
 */
public class Person implements Cloneable {

    // 不可变对象
    public String name;
    // 基本类型
    public int age;
    // 可变引用对象
    public Address address;

    public Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public Person() {
    }

    /**
     * Java 中方法重写（Override）时访问修饰符的规则：子类重写父类的方法时，访问权限可以 更宽，但不能 更窄。
     * 子类可以将父类的 protected 方法重写为 public，因为这是权限的放宽，是被允许的。
     */
    /**
     * throws CloneNotSupportedException
     * Object.clone() 方法在默认情况下会抛出这个异常：
     * 如果当前类没有实现 Cloneable 接口，调用 clone() 会抛出该异常。
     * 所以这里必须显式声明该异常或者使用 try-catch 处理它。
     * 关键点：你的类必须 implements Cloneable，否则会抛异常！
     */
    @Override
    public Object clone() throws CloneNotSupportedException {
        // 浅克隆
        /**
         * return super.clone();
         * super 表示调用父类的方法。
         * super.clone() 调用的是 Object 类中定义的 protected Object clone() 方法，它会：
         * 基于当前对象，分配一个新对象；
         * 将所有 字段按位复制（bitwise copy） 到新对象；
         * 这是浅克隆，如果有引用类型字段，需要你自己再进行深克隆（递归 clone）。
         */
        return super.clone();
    }

    /**
     * 获取
     *
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     *
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     *
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     *
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    /**
     * 获取
     *
     * @return address
     */
    public Address getAddress() {
        return address;
    }

    /**
     * 设置
     *
     * @param address
     */
    public void setAddress(Address address) {
        this.address = address;
    }

    public String toString() {
        return "Person{name = " + name + ", age = " + age + ", address = " + address + "}";
    }
}
/**
 * 浅克隆对基本类型和不可变类型通常是安全的，但对引用类型（尤其是自定义对象、集合等）会造成对象共享，必须使用深克隆。
 * <p>
 * 三种变量类型分类
 * 成员变量类型	            举例
 * 基本类型（primitive）	    int, double, char, boolean 等
 * 不可变对象（immutable）	    String, Integer, Double 等
 * 引用类型（reference）	    自定义对象、数组、集合等（如：Address, List）
 * <p>
 * 浅克隆 vs 深克隆 对不同变量的处理对比
 * 变量类型	    浅克隆处理方式	                        深克隆处理方式
 * 基本类型	    值复制 ✅（如 a = 10，完全独立）	    值复制 ✅（一样）
 * 不可变对象	    引用地址复制（但因不可变，通常是安全的）	引用地址复制或新建对象（通常不必要）
 * 可变引用类型	仅复制引用地址 ❌（对象共享，非独立）	    复制引用对象本体 ✅（手动调用 .clone() 或深拷贝）
 * <p>
 * 什么是不可变对象？
 * 不可变对象是指一旦创建，其内部状态（字段的值）就不能再被修改的对象。
 * 对象一旦被构造完成，它的内容就定下来了；
 * 所有对该对象的“修改”，其实是创建了一个新对象，原对象不变。
 * 不可变对象就是“创建后不能再改变”的对象，修改它的任何操作都会返回一个新对象，原对象保持不变。
 * <p>
 * 三种变量类型分类
 * 成员变量类型	            举例
 * 基本类型（primitive）	    int, double, char, boolean 等
 * 不可变对象（immutable）	    String, Integer, Double 等
 * 引用类型（reference）	    自定义对象、数组、集合等（如：Address, List）
 * <p>
 * 浅克隆 vs 深克隆 对不同变量的处理对比
 * 变量类型	    浅克隆处理方式	                        深克隆处理方式
 * 基本类型	    值复制 ✅（如 a = 10，完全独立）	    值复制 ✅（一样）
 * 不可变对象	    引用地址复制（但因不可变，通常是安全的）	引用地址复制或新建对象（通常不必要）
 * 可变引用类型	仅复制引用地址 ❌（对象共享，非独立）	    复制引用对象本体 ✅（手动调用 .clone() 或深拷贝）
 * <p>
 * 什么是不可变对象？
 * 不可变对象是指一旦创建，其内部状态（字段的值）就不能再被修改的对象。
 * 对象一旦被构造完成，它的内容就定下来了；
 * 所有对该对象的“修改”，其实是创建了一个新对象，原对象不变。
 * 不可变对象就是“创建后不能再改变”的对象，修改它的任何操作都会返回一个新对象，原对象保持不变。
 */
/**
 * 三种变量类型分类
 * 成员变量类型	            举例
 * 基本类型（primitive）	    int, double, char, boolean 等
 * 不可变对象（immutable）	    String, Integer, Double 等
 * 引用类型（reference）	    自定义对象、数组、集合等（如：Address, List）
 */
/**
 * 浅克隆 vs 深克隆 对不同变量的处理对比
 * 变量类型	    浅克隆处理方式	                        深克隆处理方式
 * 基本类型	    值复制 ✅（如 a = 10，完全独立）	    值复制 ✅（一样）
 * 不可变对象	    引用地址复制（但因不可变，通常是安全的）	引用地址复制或新建对象（通常不必要）
 * 可变引用类型	仅复制引用地址 ❌（对象共享，非独立）	    复制引用对象本体 ✅（手动调用 .clone() 或深拷贝）
 */
/**
 * 什么是不可变对象？
 * 不可变对象是指一旦创建，其内部状态（字段的值）就不能再被修改的对象。
 * 对象一旦被构造完成，它的内容就定下来了；
 * 所有对该对象的“修改”，其实是创建了一个新对象，原对象不变。
 * 不可变对象就是“创建后不能再改变”的对象，修改它的任何操作都会返回一个新对象，原对象保持不变。
 */